package ws.jdbc.concurrent.driver.sqlserver.tds;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import ws.jdbc.concurrent.driver.sqlserver.tds.datatypes.TYPE_VARBYTE;

/**
 * Handles the {@code ROW} token reading process.
 *
 * <p>
 * The {@code ROW} token stream used to send a complete row, as defined by the
 * {@code COLMETADATA} token, to the client.
 * </p>
 * 
 * @author Wilson Santos, 36228 <wilson.santos@ua.pt>
 */
public class RowTokenReader extends TokenReader {

  /**
   * Row column amount.
   */
  private final int columnCount;
  /**
   * Data for each column.
   */
  private final List<TYPE_VARBYTE> columnData;
  /**
   * Metadata describing each column.
   */
  private final List<ColumnData> columnsMetaData;

  /**
   * Create a new reader instance.
   * 
   * @param columnCount Row column amount.
   */
  RowTokenReader(final int columnCount) {
    this.columnCount = columnCount;
    this.columnData = new ArrayList<TYPE_VARBYTE>(columnCount);
    this.columnsMetaData = null;
  }

  /**
   * Create a new reader instance.
   *
   * @param stream data input stream to read the token from.
   * @param columnsMetaData metadata describing the columns.
   */
  RowTokenReader(final ByteBuffer stream, final List<ColumnData> columnsMetaData) {
    super(stream);

    this.columnCount = columnsMetaData.size();
    this.columnData = new ArrayList<TYPE_VARBYTE>(columnCount);
    this.columnsMetaData = columnsMetaData;
  }

  /**
   * Read one {@code ROW} token.
   *
   * @return number of bytes read.
   *
   * @throws IOException if an error occurs while reading from the data input stream.
   */
  @Override
  int read() throws IOException {
    // Token definition: AllColumnData = *ColumnData
    // ColumnData
    //  [TextPointer]...
    //  [Timestamp]...
    //  Data
    for (int i = 0; i < columnCount; ++i) {
      TYPE_VARBYTE colData = dtddsReader.readTypeVarByte(columnsMetaData.get(i).getTypeInfo());
      columnData.add(colData);
    }
    return dtddsReader.getBytesRead();
  }

  public TYPE_VARBYTE getData(int columnIndex) {
    return columnData.get(columnIndex);
  }

  public void addData(int columnIndex, TYPE_VARBYTE data) {
    columnData.add(columnIndex, data);
  }

  public void setData(int columnIndex, TYPE_VARBYTE data) {
    columnData.set(columnIndex, data);
  }

  /**
   * Token as a {@code String}.
   *
   * @return token fields as a {@code String}.
   */
  @Override
  public String toString() {
    String ret = "RowTokenReader{";
    for (TYPE_VARBYTE col : columnData) {
      System.out.println("COL=" + col);
      ret += "\n" + col.toString();
    }
    return ret + "\n}";
  }
}
